home *** CD-ROM | disk | FTP | other *** search
-
- const Cc = Components.classes;
- const Ci = Components.interfaces;
- const Cr = Components.results;
-
- const PREFS_DOMAIN = "extensions.firegestures.";
- const HTML_NS = "http://www.w3.org/1999/xhtml";
-
- const STATE_READY = 0;
- const STATE_GESTURE = 1;
- const STATE_ROCKER = 2;
- const STATE_WHEEL = 3;
- const STATE_KEYPRESS = 4;
-
- Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-
-
-
-
-
- function xdGestureHandler() {}
-
-
- xdGestureHandler.prototype = {
-
-
- classDescription: "Mouse Gesture Handler",
- contractID: "@xuldev.org/firegestures/handler;1",
- classID: Components.ID("{ca559550-8ab4-41c5-a72f-fd931322cc7e}"),
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsISupports,
- Ci.nsIObserver,
- Ci.nsISupportsWeakReference,
- Ci.nsIDOMEventListener,
- Ci.nsITimerCallback,
- Ci.xdIGestureHandler
- ]),
-
-
-
- sourceNode: null,
-
-
-
- _drawArea: null,
- _lastX: null,
- _lastY: null,
- _directionChain: "",
-
- _gestureObserver: null,
-
-
-
- attach: function FGH_attach(aDrawArea, aObserver) {
- this._drawArea = aDrawArea;
- this._gestureObserver = aObserver;
- this._drawArea.addEventListener("mousedown", this, true);
- this._drawArea.addEventListener("mousemove", this, true);
- this._drawArea.addEventListener("mouseup", this, true);
- this._drawArea.addEventListener("contextmenu", this, true);
- this._drawArea.addEventListener("draggesture", this, true);
- this._reloadPrefs();
- var prefBranch2 = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
- prefBranch2.addObserver(PREFS_DOMAIN, this, true);
- },
-
- detach: function FGH_detach() {
- this._drawArea.removeEventListener("mousedown", this, true);
- this._drawArea.removeEventListener("mousemove", this, true);
- this._drawArea.removeEventListener("mouseup", this, true);
- this._drawArea.removeEventListener("contextmenu", this, true);
- this._drawArea.removeEventListener("draggesture", this, true);
- var prefBranch2 = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
- prefBranch2.removeObserver(PREFS_DOMAIN, this);
- this._clearTimeout();
- this.sourceNode = null;
- this._drawArea = null;
- this._gestureObserver = null;
- this._prefs = null;
- },
-
- _reloadPrefs: function FGH__reloadPrefs() {
- var prefBranch = Cc["@mozilla.org/preferences-service;1"]
- .getService(Ci.nsIPrefService)
- .getBranch(PREFS_DOMAIN);
- var getPref = function(aName) {
- try {
- switch (prefBranch.getPrefType(aName)) {
- case prefBranch.PREF_STRING:
- return prefBranch.getCharPref(aName);
- case prefBranch.PREF_BOOL:
- return prefBranch.getBoolPref(aName);
- case prefBranch.PREF_INT:
- return prefBranch.getIntPref(aName);
- default:
- throw null;
- }
- }
- catch(ex) {
- }
- };
- this._triggerButton = getPref("trigger_button");
- this._suppressAlt = getPref("suppress.alt");
- this._trailEnabled = getPref("mousetrail");
- this._trailSize = getPref("mousetrail.size");
- this._trailColor = getPref("mousetrail.color");
- this._gestureTimeout = getPref("gesture_timeout");
- this._mouseGestureEnabled = getPref("mousegesture");
- this._wheelGestureEnabled = getPref("wheelgesture");
- this._rockerGestureEnabled = getPref("rockergesture");
- this._keypressGestureEnabled = getPref("keypressgesture");
- this._drawArea.removeEventListener("DOMMouseScroll", this, true);
- this._drawArea.removeEventListener("click", this, true);
- if (this._wheelGestureEnabled)
- this._drawArea.addEventListener("DOMMouseScroll", this, true);
- if (this._rockerGestureEnabled)
- this._drawArea.addEventListener("click", this, true);
- var tabbrowser = this._drawArea.ownerDocument.getBindingParent(this._drawArea);
- if (tabbrowser && tabbrowser.localName == "tabbrowser") {
- tabbrowser.mStrip.removeEventListener("DOMMouseScroll", this._wheelOnTabBar, true);
- if (getPref("tabwheelgesture"))
- tabbrowser.mStrip.addEventListener("DOMMouseScroll", this._wheelOnTabBar, true);
- }
- if (this._triggerButton == 1) {
- var prefSvc = Cc["@mozilla.org/preferences-service;1"]
- .getService(Ci.nsIPrefBranch2)
- .QueryInterface(Ci.nsIPrefService);
- prefSvc.setBoolPref("middlemouse.contentLoadURL", false);
- }
- },
-
-
-
- _state: STATE_READY,
- _isMouseDownL: false,
- _isMouseDownM: false,
- _isMouseDownR: false,
- _suppressContext: false,
- _shouldFireContext: false,
-
- handleEvent: function FGH_handleEvent(event) {
- switch (event.type) {
- case "mousedown":
- if (event.button == 0) {
- var targetName = event.target.localName.toUpperCase();
- if (targetName == "INPUT" || targetName == "TEXTAREA") {
- break;
- }
- targetName = event.originalTarget.localName;
- if (targetName == "scrollbarbutton" || targetName == "slider" || targetName == "thumb") {
- break;
- }
- this._isMouseDownL = true;
- this._isMouseDownM = false;
- if (this._triggerButton == 0 && !this._isMouseDownM && !this._isMouseDownR && !this._altKey(event)) {
- this._state = STATE_GESTURE;
- this._startGesture(event);
- if (this._mouseGestureEnabled)
- event.preventDefault();
- }
- else if (this._rockerGestureEnabled && this._isMouseDownR) {
- this._state = STATE_ROCKER;
- this._invokeExtraGesture(event, "rocker-left");
- }
- }
- else if (event.button == 1) {
- this._isMouseDownM = true;
- if (this._triggerButton == 1 && !this._isMouseDownL && !this._isMouseDownR && !this._altKey(event)) {
- this._state = STATE_GESTURE;
- this._startGesture(event);
- event.stopPropagation();
- }
- }
- else if (event.button == 2) {
- var targetName = event.target.localName.toUpperCase();
- if (targetName == "OBJECT" || targetName == "EMBED") {
- break;
- }
- this._isMouseDownR = true;
- this._isMouseDownM = false;
- this._suppressContext = false;
- if (this._triggerButton == 2 && !this._isMouseDownL && !this._isMouseDownM && !this._altKey(event)) {
- this._state = STATE_GESTURE;
- this._startGesture(event);
- }
- else if (this._rockerGestureEnabled && this._isMouseDownL) {
- this._state = STATE_ROCKER;
- this._invokeExtraGesture(event, "rocker-right");
- }
- }
- break;
- case "mousemove":
- if (this._state == STATE_GESTURE || this._state == STATE_KEYPRESS) {
- if (this._mouseGestureEnabled) {
- if (this._keypressGestureEnabled && (event.ctrlKey || event.shiftKey)) {
- var type = this._state == STATE_GESTURE ? "keypress-start" : "keypress-progress";
- this._state = STATE_KEYPRESS;
- this._invokeExtraGesture(event, type);
- }
- this._progressGesture(event);
- }
- }
- else if (this._state == STATE_WHEEL || this._state == STATE_ROCKER) {
- this._lastX = event.screenX;
- this._lastY = event.screenY;
- if (Math.abs(this._lastX - this._lastExtraX) > 10 ||
- Math.abs(this._lastY - this._lastExtraY) > 10) {
- this._stopGesture();
- }
- }
- break;
- case "mouseup":
- if (event.button == 0)
- this._isMouseDownL = false;
- else if (event.button == 1)
- this._isMouseDownM = false;
- else if (event.button == 2)
- this._isMouseDownR = false;
- if (!this._isMouseDownL && !this._isMouseDownM && !this._isMouseDownR) {
- if (this._state == STATE_KEYPRESS) {
- this._state = STATE_READY;
- if (event.ctrlKey)
- this._invokeExtraGesture(event, "keypress-ctrl");
- else if (event.shiftKey)
- this._invokeExtraGesture(event, "keypress-shift");
- this._invokeExtraGesture(event, "keypress-stop");
- }
- this._stopGesture(event);
- if (this._shouldFireContext) {
- this._shouldFireContext = false;
- this._displayContextMenu(event);
- }
- }
- break;
- case "contextmenu":
- if (!this._isMouseDownL && this._isMouseDownR) {
- this._suppressContext = true;
- this._shouldFireContext = true;
- }
- if (this._suppressContext) {
- this._suppressContext = false;
- event.preventDefault();
- event.stopPropagation();
- }
- break;
- case "DOMMouseScroll":
- if (this._state == STATE_GESTURE || this._state == STATE_WHEEL) {
- this._state = STATE_WHEEL;
- this._invokeExtraGesture(event, event.detail < 0 ? "wheel-up" : "wheel-down");
- event.preventDefault();
- event.stopPropagation();
- }
- break;
- case "click":
- if (this._state == STATE_ROCKER) {
- event.preventDefault();
- event.stopPropagation();
- }
- break;
- case "draggesture":
- if (this._state != STATE_ROCKER)
- this._isMouseDownL = false;
- break;
- }
- },
-
- _altKey: function(event) {
- return this._suppressAlt ? event.altKey : false;
- },
-
- _displayContextMenu: function FGH__displayContextMenu(event) {
- with (this._drawArea.ownerDocument.defaultView) {
- if (!nsContextMenu.prototype._setTargetInternal) {
- nsContextMenu.prototype._setTargetInternal = nsContextMenu.prototype.setTarget;
- nsContextMenu.prototype.setTarget = function(aNode, aRangeParent, aRangeOffset) {
- this._setTargetInternal(aNode, aRangeParent, this._rangeOffset);
- };
- }
- nsContextMenu.prototype._rangeOffset = event.rangeOffset;
- }
- var evt = event.originalTarget.ownerDocument.createEvent("MouseEvents");
- evt.initMouseEvent(
- "contextmenu", true, true, event.originalTarget.ownerDocument.defaultView, 0,
- event.screenX, event.screenY, event.clientX, event.clientY,
- false, false, false, false, 2, null
- );
- event = new XPCNativeWrapper(event);
- event.originalTarget.dispatchEvent(evt);
- },
-
- _wheelOnTabBar: function FGH__wheelOnTabBar(event) {
- var tabbar = null;
- if (event.target.localName == "tab")
- tabbar = event.target.parentNode;
- else if (event.target.localName == "tabs" && event.originalTarget.localName != "menuitem")
- tabbar = event.target;
- else
- return;
- event.preventDefault();
- event.stopPropagation();
- tabbar.advanceSelectedTab(event.detail < 0 ? -1 : 1, true);
- },
-
- _startGesture: function FGH__startGesture(event) {
- this.sourceNode = event.target;
- this._lastX = event.screenX;
- this._lastY = event.screenY;
- this._directionChain = "";
- this._shouldFireContext = false;
- if (this._trailEnabled)
- this.createTrail(event);
- },
-
- _progressGesture: function FGH__progressGesture(event) {
- var x = event.screenX;
- var y = event.screenY;
- var dx = Math.abs(x - this._lastX);
- var dy = Math.abs(y - this._lastY);
- if (dx < 10 && dy < 10)
- return;
- var direction;
- if (dx > dy)
- direction = x < this._lastX ? "L" : "R";
- else
- direction = y < this._lastY ? "U" : "D";
- if (this._trailEnabled)
- this.drawTrail(this._lastX, this._lastY, x, y);
- this._lastX = x;
- this._lastY = y;
- if (this._state == STATE_KEYPRESS)
- return;
- var lastDirection = this._directionChain.charAt(this._directionChain.length - 1);
- if (direction != lastDirection) {
- this._directionChain += direction;
- this._gestureObserver.onDirectionChanged(event, this._directionChain);
- }
- if (this._gestureTimeout > 0)
- this._setTimeout(this._gestureTimeout);
- },
-
- _invokeExtraGesture: function FGH__invokeExtraGesture(event, aGestureType) {
- if (this._state == STATE_WHEEL || this._state == STATE_ROCKER) {
- this._lastExtraX = event.screenX;
- this._lastExtraY = event.screenY;
- }
- if (this._state != STATE_KEYPRESS && this._trailEnabled)
- this.eraseTrail();
- this._gestureObserver.onExtraGesture(event, aGestureType);
- this._suppressContext = true;
- this._shouldFireContext = false;
- this._directionChain = "";
- if (this._state == STATE_WHEEL || this._state == STATE_ROCKER) {
- if (this._gestureTimeout > 0)
- this._setTimeout(this._gestureTimeout);
- }
- },
-
- _stopGesture: function FGH__stopGesture(event) {
- this._state = STATE_READY;
- this._isMouseDownL = false;
- this._isMouseDownM = false;
- this._isMouseDownR = false;
- if (this._trailEnabled)
- this.eraseTrail();
- if (this._directionChain) {
- this._gestureObserver.onMouseGesture(event, this._directionChain);
- this._suppressContext = true;
- this._shouldFireContext = false;
- }
- this.sourceNode = null;
- this._directionChain = "";
- this._clearTimeout();
- },
-
-
-
- observe: function FGH_observe(aSubject, aTopic, aData) {
- if (aTopic == "nsPref:changed")
- this._reloadPrefs();
- },
-
-
-
- _gestureTimer: null,
-
- _setTimeout: function FGH__setTimeout(aMsec) {
- this._clearTimeout();
- this._gestureTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this._gestureTimer.initWithCallback(this, aMsec, Ci.nsITimer.TYPE_ONE_SHOT);
- },
-
- _clearTimeout: function FGH__clearTimeout() {
- if (this._gestureTimer) {
- this._gestureTimer.cancel();
- this._gestureTimer = null;
- }
- },
-
- notify: function(aTimer) {
- this._suppressContext = true;
- this._shouldFireContext = false;
- this._directionChain = "";
- this._stopGesture();
- this._gestureObserver.onExtraGesture(null, "gesture-timeout");
- },
-
- openPopupAtPointer: function FGH_openPopupAtPointer(aPopup) {
- aPopup.openPopupAtScreen(this._lastX, this._lastY, false);
- this._directionChain = "";
- this._stopGesture();
- },
-
-
-
- _trailDot: null,
- _trailArea: null,
- _trailLastDot: null,
- _trailOffsetX: 0,
- _trailOffsetY: 0,
- _trailZoom: 1,
-
- createTrail: function FGH_createTrail(event) {
- var doc;
- if (event.view.top.document instanceof Ci.nsIDOMHTMLDocument)
- doc = event.view.top.document;
- else if (event.view.document instanceof Ci.nsIDOMHTMLDocument)
- doc = event.view.document;
- else
- return;
- var insertionNode = doc.documentElement ? doc.documentElement : doc;
- if (doc.getBoxObjectFor) {
- var box = doc.getBoxObjectFor(insertionNode);
- this._trailOffsetX = box.screenX;
- this._trailOffsetY = box.screenY;
- this._trailZoom = 1;
- var tabbrowser = this._drawArea.ownerDocument.defaultView.gBrowser;
- if (tabbrowser && (tabbrowser.mCurrentBrowser || tabbrowser).markupDocumentViewer.fullZoom != 1) {
- var dot = doc.createElementNS(HTML_NS, "xdTrailDot");
- dot.style.top = "1048576px";
- dot.style.position = "absolute";
- insertionNode.appendChild(dot);
- this._trailZoom = (doc.getBoxObjectFor(dot).screenY - this._trailOffsetY) / dot.offsetTop;
- insertionNode.removeChild(dot);
- }
- }
- else {
- var win = doc.defaultView;
- this._trailZoom = win.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils).screenPixelsPerCSSPixel;
- this._trailOffsetX = (win.mozInnerScreenX - win.scrollX) * this._trailZoom;
- this._trailOffsetY = (win.mozInnerScreenY - win.scrollY) * this._trailZoom;
- }
- this._trailArea = doc.createElementNS(HTML_NS, "xdTrailArea");
- insertionNode.appendChild(this._trailArea);
- this._trailDot = doc.createElementNS(HTML_NS, "xdTrailDot");
- this._trailDot.style.width = this._trailSize + "px";
- this._trailDot.style.height = this._trailSize + "px";
- this._trailDot.style.background = this._trailColor;
- this._trailDot.style.border = "0px";
- this._trailDot.style.position = "absolute";
- this._trailDot.style.zIndex = 2147483647;
- },
-
- drawTrail: function FGH_drawTrail(x1, y1, x2, y2) {
- if (!this._trailArea)
- return;
- var xMove = x2 - x1;
- var yMove = y2 - y1;
- var xDecrement = xMove < 0 ? 1 : -1;
- var yDecrement = yMove < 0 ? 1 : -1;
- x2 -= this._trailOffsetX;
- y2 -= this._trailOffsetY;
- if (Math.abs(xMove) >= Math.abs(yMove))
- for (var i = xMove; i != 0; i += xDecrement)
- this._strokeDot(x2 - i, y2 - Math.round(yMove * i / xMove));
- else
- for (var i = yMove; i != 0; i += yDecrement)
- this._strokeDot(x2 - Math.round(xMove * i / yMove), y2 - i);
- },
-
- eraseTrail: function FGH_eraseTrail() {
- if (this._trailArea && this._trailArea.parentNode) {
- while (this._trailArea.lastChild)
- this._trailArea.removeChild(this._trailArea.lastChild);
- this._trailArea.parentNode.removeChild(this._trailArea);
- }
- this._trailDot = null;
- this._trailArea = null;
- this._trailLastDot = null;
- },
-
- _strokeDot: function FGH__strokeDot(x, y) {
- if (this._trailArea.y == y && this._trailArea.h == this._trailSize) {
- var newX = Math.min(this._trailArea.x, x);
- var newW = Math.max(this._trailArea.x + this._trailArea.w, x + this._trailSize) - newX;
- this._trailArea.x = newX;
- this._trailArea.w = newW;
- this._trailLastDot.style.left = newX.toString() + "px";
- this._trailLastDot.style.width = newW.toString() + "px";
- return;
- }
- else if (this._trailArea.x == x && this._trailArea.w == this._trailSize) {
- var newY = Math.min(this._trailArea.y, y);
- var newH = Math.max(this._trailArea.y + this._trailArea.h, y + this._trailSize) - newY;
- this._trailArea.y = newY;
- this._trailArea.h = newH;
- this._trailLastDot.style.top = newY.toString() + "px";
- this._trailLastDot.style.height = newH.toString() + "px";
- return;
- }
- if (this._trailZoom != 1) {
- x = Math.floor(x / this._trailZoom);
- y = Math.floor(y / this._trailZoom);
- }
- var dot = this._trailDot.cloneNode(true);
- dot.style.left = x + "px";
- dot.style.top = y + "px";
- this._trailArea.x = x;
- this._trailArea.y = y;
- this._trailArea.w = this._trailSize;
- this._trailArea.h = this._trailSize;
- this._trailArea.appendChild(dot);
- this._trailLastDot = dot;
- },
-
- };
-
-
-
- function NSGetModule(compMgr, fileSpec) {
- return XPCOMUtils.generateModule([xdGestureHandler]);
- }
-
-
-